package com.bstech.Tabelle;

import java.io.StringWriter;
import java.util.List;
import java.util.Vector;

import org.acra.ErrorReporter;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xmlpull.v1.XmlSerializer;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import com.bstech.Classi.Common;
import com.bstech.Utils.*;

public class RapportiniDettaglio {
	public static String TABLE_NAME = "RAPPORTINI_DETTAGLIO";
	
	public static String ID_KEY = "ID";
	public static String ID_RAPPORTINO_KEY = "ID_RAPPORTINO";
	public static String CODICE_KEY = "CODICE";
	public static String GRUPPO_KEY = "GRUPPO";
	public static String COMPONENTE_KEY = "COMPONENTE";
	public static String DESCRIZIONE_KEY = "DESCRIZIONE";
	public static String ESEGUITO_KEY = "ESEGUITO";
	public static String MODIFICATO_KEY = "MODIFICATO";
	

	public static String CREATE_TABLE_QUERY = "CREATE TABLE IF NOT EXISTS "+ TABLE_NAME +"(" +
												ID_KEY+" integer primary key not null," +
												ID_RAPPORTINO_KEY+" integer not null," +
												CODICE_KEY+" integer not null," +
												GRUPPO_KEY+" text null," +
												COMPONENTE_KEY+" integer null," +
												DESCRIZIONE_KEY+" text null," +
												ESEGUITO_KEY+" integer not null,"+
												MODIFICATO_KEY+" integer not null);";
	
	public static void UpdateToVersion(SQLiteDatabase db, int from, int to )
	{
		for(int ver = from +1; ver<= to; ver++)
		{
			switch(ver)
			{
			case 3:
				db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN " + COMPONENTE_KEY + " integer null");
				break;
			}
		}
	}
	public static boolean Insert(int ID, int IdRapportino, int Codice, String Gruppo, int Componente, String Descrizione, int Eseguito, boolean Modificato)
	{
		ContentValues cv = new ContentValues();
		
		cv.put(RapportiniDettaglio.ID_KEY, ID);
		cv.put(RapportiniDettaglio.ID_RAPPORTINO_KEY, IdRapportino);
		cv.put(RapportiniDettaglio.CODICE_KEY, Codice);
		cv.put(RapportiniDettaglio.GRUPPO_KEY, Strings.CheckString(Gruppo));
		cv.put(RapportiniDettaglio.COMPONENTE_KEY, Componente);
		cv.put(RapportiniDettaglio.DESCRIZIONE_KEY, Strings.CheckString(Descrizione));
		cv.put(RapportiniDettaglio.ESEGUITO_KEY, Eseguito);
		cv.put(RapportiniDettaglio.MODIFICATO_KEY, Modificato ? -1 : 0);
		
		return Common.db.Insert(RapportiniDettaglio.TABLE_NAME, null, cv);
	}	
	public static boolean Update(int ID, int IdRapportino, int Codice, String Gruppo, int Componente, String Descrizione, int Eseguito, boolean modificato)
	{
		ContentValues cv = new ContentValues();
		
		cv.put(RapportiniDettaglio.ID_RAPPORTINO_KEY, IdRapportino);
		cv.put(RapportiniDettaglio.CODICE_KEY, Codice);
		cv.put(RapportiniDettaglio.GRUPPO_KEY, Strings.CheckString(Gruppo));
		cv.put(RapportiniDettaglio.COMPONENTE_KEY, Componente);
		cv.put(RapportiniDettaglio.DESCRIZIONE_KEY, Strings.CheckString(Descrizione));
		cv.put(RapportiniDettaglio.ESEGUITO_KEY, Eseguito);
		cv.put(RapportiniDettaglio.MODIFICATO_KEY, modificato ? -1 : 0);
		
		return Common.db.Update(RapportiniDettaglio.TABLE_NAME, cv,RapportiniDettaglio.ID_KEY +" = " + Integer.toString(ID), null);
	}	
	public static boolean UpdateEseguito(int ID, int Eseguito)
	{
		ContentValues cv = new ContentValues();
		
		cv.put(RapportiniDettaglio.ESEGUITO_KEY, Eseguito);
		cv.put(RapportiniDettaglio.MODIFICATO_KEY, -1);
		
		return Common.db.Update(RapportiniDettaglio.TABLE_NAME, cv,RapportiniDettaglio.ID_KEY +" = " + Integer.toString(ID), null);
	}	
	public static List<RapportinoDettaglio> SelectGruppo(int idRapportino, String Gruppo)
	{
		Cursor cursor = Common.db.query(RapportiniDettaglio.TABLE_NAME, new String[] {RapportiniDettaglio.ID_KEY,RapportiniDettaglio.ID_RAPPORTINO_KEY,RapportiniDettaglio.CODICE_KEY,
																					  RapportiniDettaglio.GRUPPO_KEY,RapportiniDettaglio.COMPONENTE_KEY,RapportiniDettaglio.DESCRIZIONE_KEY,RapportiniDettaglio.ESEGUITO_KEY},
						RapportiniDettaglio.ID_RAPPORTINO_KEY + "=" + Integer.toString(idRapportino) + " AND " + RapportiniDettaglio.GRUPPO_KEY + " = '" + Strings.CheckString(Gruppo) +"'",
						null, null,null, 
						RapportiniDettaglio.CODICE_KEY);
		
		List<RapportinoDettaglio> ret = new Vector<RapportinoDettaglio>();
		
		if(cursor != null)
		{
			while(cursor.moveToNext())
				ret.add(Select(cursor));
			cursor.close();
		}
		
		return ret;
	}
	public static List<RapportinoDettaglio> SelectAll(int idRapportino)
	{
		Cursor cursor = Common.db.query(RapportiniDettaglio.TABLE_NAME, new String[] {RapportiniDettaglio.ID_KEY,RapportiniDettaglio.ID_RAPPORTINO_KEY,RapportiniDettaglio.CODICE_KEY,
																					  RapportiniDettaglio.GRUPPO_KEY,RapportiniDettaglio.COMPONENTE_KEY,RapportiniDettaglio.DESCRIZIONE_KEY,RapportiniDettaglio.ESEGUITO_KEY},
						RapportiniDettaglio.ID_RAPPORTINO_KEY + "=" + Integer.toString(idRapportino),null, null,null,RapportiniDettaglio.CODICE_KEY);
		
		List<RapportinoDettaglio> ret = new Vector<RapportinoDettaglio>();
		
		if(cursor != null)
		{
			while(cursor.moveToNext())
				ret.add(Select(cursor));
			cursor.close();
		}
		
		return ret;
	}
	public static List<RapportinoDettaglio> SelectAllModificati(int idRapportino)
	{
		Cursor cursor = Common.db.query(RapportiniDettaglio.TABLE_NAME, new String[] {RapportiniDettaglio.ID_KEY,RapportiniDettaglio.ID_RAPPORTINO_KEY,RapportiniDettaglio.CODICE_KEY,
																					  RapportiniDettaglio.GRUPPO_KEY,RapportiniDettaglio.COMPONENTE_KEY,RapportiniDettaglio.DESCRIZIONE_KEY,RapportiniDettaglio.ESEGUITO_KEY},
						RapportiniDettaglio.ID_RAPPORTINO_KEY + "=" + Integer.toString(idRapportino) + " AND "+ RapportiniDettaglio.MODIFICATO_KEY + "<> 0",null, null,null,RapportiniDettaglio.CODICE_KEY);
		
		List<RapportinoDettaglio> ret = new Vector<RapportinoDettaglio>();
		
		if(cursor != null)
		{
			while(cursor.moveToNext())
				ret.add(Select(cursor));
			cursor.close();
		}
		
		return ret;
	}
	public static List<String> SelectGruppi(int idRapportino)
	{
		Cursor cursor = Common.db.query(RapportiniDettaglio.TABLE_NAME, new String[] {RapportiniDettaglio.GRUPPO_KEY},
						RapportiniDettaglio.ID_RAPPORTINO_KEY + "=" + Integer.toString(idRapportino),
						null, RapportiniDettaglio.GRUPPO_KEY ,null, 
						RapportiniDettaglio.CODICE_KEY);
		
		List<String> ret = new Vector<String>();
		
		if(cursor != null)
		{
			while(cursor.moveToNext())
				ret.add(cursor.getString(0));
			cursor.close();
		}
		
		return ret;
	}
	public static boolean Exists(int idRappDettaglio) {
		Cursor cursor = Common.db.query(RapportiniDettaglio.TABLE_NAME,new String[] { RapportiniDettaglio.ID_KEY }, RapportiniDettaglio.ID_KEY + "=" + Integer.toString(idRappDettaglio), null, null, null, null);

		int count = 0;
		if (cursor != null) {
			count = cursor.getCount();
			cursor.close();
		}
		return (count > 0);
	}
	private static RapportinoDettaglio Select(Cursor cursor)
	{
		RapportinoDettaglio ret = null;
		
		if(cursor != null && !cursor.isAfterLast())
		{	
			ret = new RapportinoDettaglio();
			
			ret.ID = cursor.getInt(0);
			ret.IdRapportino = cursor.getInt(1);
			ret.Codice = cursor.getInt(2);
			ret.Gruppo = cursor.getString(3);
			ret.Componente = cursor.getInt(4);
			ret.Descrizione = cursor.getString(5);
			ret.Eseguito = cursor.getInt(6);
		}
		return ret;
	}
	public static void Storicizza()
	{
		Common.db.executeSql("DELETE FROM "+ RapportiniDettaglio.TABLE_NAME +" WHERE "+ RapportiniDettaglio.MODIFICATO_KEY +" = 0");
	}
	public static int CreateNew(int IdRapportino, String Descrizione)
	{
		Common.db.BeginTransaction();
		
		int idDett = DbFunctions.GetNewID(RapportiniDettaglio.TABLE_NAME);
		if(idDett != 0)
		{
			if(!RapportiniDettaglio.Insert(idDett, IdRapportino, -1, null, -1, Descrizione, -1, true))
				idDett = 0;
		}
		else
			Log.e("RapportiniDettaglio.CreateNew", "Errore creazione ID nuovo rapportino, IdRapportino: " + Integer.toString(IdRapportino));
		
		if(idDett != 0)
			Common.db.Commit();
		else
			Common.db.Rollback();
		
		return idDett;
	}
	
	public static class RapportinoDettaglio
	{
		public RapportinoDettaglio(){}
		public int ID,IdRapportino,Codice,Componente,Eseguito;
		public String Gruppo,Descrizione;
		
		public static String GetXml(RapportinoDettaglio item)
		{
			String ret = null;
			
			XmlSerializer serializer = XmlParser.CreateSerializer();
	        StringWriter writer = new StringWriter();
	        
	        try {
	                serializer.setOutput(writer);
	                serializer.startDocument("UTF-8", true);

    				serializer.startTag("", "RAPPORTINI_DETTAGLIO");
    				XmlParser.addTagAndValue(serializer, "ID",Integer.toString(item.ID));
    				XmlParser.addTagAndValue(serializer, "AS04_RAPPORTINO_AS02",Integer.toString(item.IdRapportino));
    				XmlParser.addTagAndValue(serializer, "AS04_CODICE",Integer.toString(item.Codice));
    				XmlParser.addTagAndValue(serializer, "AS04_GRUPPO",item.Gruppo);
    				XmlParser.addTagAndValue(serializer, "AS04_COMPONENTE",Integer.toString(item.Componente));
    				XmlParser.addTagAndValue(serializer, "AS04_DESCRIZIONE",item.Descrizione);
    				XmlParser.addTagAndValue(serializer, "AS04_ESEGUITO",Integer.toString(item.Eseguito));
    				serializer.endTag("", "RAPPORTINI_DETTAGLIO");

	                serializer.endDocument();
	                ret = writer.toString();
	                
	                writer.close();
	                writer = null;
	                serializer = null;
	        } catch (Exception e) {
	        	Log.e("Rapportino.GetXml", "Errore durante la creazione di un nodo. Errore: " + e.toString());
				ErrorReporter.getInstance().handleException(e);
	        }
			
	        return ret;
		}
		public static List<RapportinoDettaglio> GetFromXml(String xml)
		{
			List<RapportinoDettaglio> ret = new Vector<RapportinoDettaglio>();
			
			if(xml !=null)
			{
				NodeList nodi = XmlParser.ParseNodes(xml, "RAPPORTINI_DETTAGLIO");
				if(nodi !=null)
				{
					int nodesCount = nodi.getLength();
					RapportinoDettaglio r = null;
					
					for(int i=0; i < nodesCount; i++)
					{
						r = ParseFromXmlNode(nodi.item(i));
						if(r != null)
							ret.add(r);
					}
					
					r = null;
					nodi = null;
				}
				else
					Log.e("RapportinoDettaglio.GetFromXml", "Errore durante il parse dei nodi, ritornato null");
			}
			else
				Log.e("RapportinoDettaglio.GetFromXml", "Parametro xml nullo");
			
			return ret;
		}
		private static RapportinoDettaglio ParseFromXmlNode(Node nodo) {
			RapportinoDettaglio ret = new RapportinoDettaglio();
			
			NodeList dettagli = nodo.getChildNodes();
			int detailsCount = dettagli.getLength();
			
			Element dettaglio = null;
			String nome = "";
			String valore = "";
			
			for(int i=0;i<detailsCount;i++)
			{
				try {
					if(dettagli.item(i).getNodeType() == Node.ELEMENT_NODE)
					{
						dettaglio = (Element)dettagli.item(i);
						nome = dettaglio.getNodeName();
						valore = dettaglio.getTextContent();
						
						if(nome.equals("ID"))
							ret.ID = Integer.parseInt(valore.trim());
						else if(nome.equals("AS04_RAPPORTINO_AS02"))
							ret.IdRapportino  = Integer.parseInt(valore.trim());
						else if(nome.equals("AS04_CODICE"))
							ret.Codice = Integer.parseInt(valore.trim());
						else if(nome.equals("AS04_GRUPPO"))
							ret.Gruppo = valore.trim();
						else if(nome.equals("AS04_COMPONENTE"))
							ret.Componente = Integer.parseInt(valore.trim());
						else if(nome.equals("AS04_DESCRIZIONE"))
							ret.Descrizione = valore.trim();
						else if(nome.equals("AS04_ESEGUITO"))
							ret.Eseguito = Integer.parseInt(valore.trim());
					}
				} catch (Exception e) {
					Log.e("RapportinoDettaglio.ParseFromXmlNode", "Errore nel ciclo di assegnazione valori. Errore: " + e.toString());
					ret = null;
					break;
				}
			}
			
			dettaglio = null;
			dettagli = null;
			
			return ret;
		}
		public boolean ImpostaModificato(boolean stato)
		{
			try {
				ContentValues cv = new ContentValues();
				cv.put(RapportiniDettaglio.MODIFICATO_KEY, stato ? -1 : 0);
				Log.v("Update flag MODIFICATO RapportiniDettaglio", "IDRapportinoDettaglio: " + Integer.toString(ID));
				return Common.db.Update(RapportiniDettaglio.TABLE_NAME, cv, RapportiniDettaglio.ID_KEY + " = " + Integer.toString(ID), null);
			} catch (Exception e) {
				return false;
			}
		}
		public boolean AggiornaID(int nuovoID)
		{
			try {
				Log.v("Update ID Rapportino Dettaglio", "IDRapportinoDettaglio: " + Integer.toString(ID));
				
				ContentValues cv = new ContentValues();
				cv.put(RapportiniDettaglio.ID_KEY, nuovoID);
				Common.db.Update(RapportiniDettaglio.TABLE_NAME, cv, RapportiniDettaglio.ID_KEY + " = " + Integer.toString(ID), null);
				return true;
			} catch (Exception e) {
				return false;
			}
		}
		public void AggiornaIDRapportino(int nuovoID)
		{
			//aggiorno id su record chiamata
			Log.v("Update ID Dettaglio Rapportino", "IDRapportinoDettaglio: " + Integer.toString(ID));
			
			ContentValues cv = new ContentValues();
			cv.put(RapportiniDettaglio.ID_RAPPORTINO_KEY, nuovoID);
			Common.db.Update(RapportiniDettaglio.TABLE_NAME, cv, RapportiniDettaglio.ID_KEY + " = " + Integer.toString(ID), null);
		}
	}
}
